import bcrypt from 'bcryptjs'
import mongoose, { Document, Schema } from 'mongoose'
import { levelConfig } from '../config/level'

export interface IUser extends Document {
  username: string
  password: string
  nickname: string
  avatar: string
  phone: string
  email: string
  level: number
  exp: number
  coins: number
  income: number
  badges: Array<{
    name: string
    icon: string
    obtainTime?: Date
  }>
  titles: Array<{
    name: string
    icon: string
    obtainTime?: Date
  }>
  privileges: string[]
  vipLevel: number
  vipExpireTime: Date
  roomId: string
  followers: number
  following: number
  blockedUsers: string[]
  lastLoginTime: Date
  lastLoginIp: string
  status: 'active' | 'banned' | 'deleted'
  isAnchor: boolean
  anchorInfo?: {
    category: string
    tags: string[]
    description: string
    notice: string
    totalLiveTime: number
    totalIncome: number
    fansCount: number
    guardCount: number
  }
  bankInfo?: {
    realName: string
    idCard: string
    bankName: string
    bankAccount: string
    bankBranch: string
  }
  settings: {
    notification: {
      follow: boolean
      gift: boolean
      message: boolean
      roomStart: boolean
    }
    privacy: {
      showLastSeen: boolean
      showPhone: boolean
      allowPrivateMessage: boolean
    }
    display: {
      theme: 'light' | 'dark'
      fontSize: number
      language: string
    }
  }
  createdAt: Date
  updatedAt: Date
}

const UserSchema = new Schema(
  {
    username: {
      type: String,
      required: true,
      unique: true,
      trim: true,
      minlength: 3,
      maxlength: 20,
    },
    password: {
      type: String,
      required: true,
      select: false,
    },
    nickname: {
      type: String,
      required: true,
      trim: true,
      minlength: 2,
      maxlength: 20,
    },
    avatar: {
      type: String,
      default: '/avatars/default.png',
    },
    phone: {
      type: String,
      unique: true,
      sparse: true,
      validate: {
        validator: function (v: string) {
          return /^1[3-9]\d{9}$/.test(v)
        },
        message: '请输入正确的手机号码',
      },
    },
    email: {
      type: String,
      unique: true,
      sparse: true,
      lowercase: true,
      validate: {
        validator: function (v: string) {
          return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(v)
        },
        message: '请输入正确的邮箱地址',
      },
    },
    level: {
      type: Number,
      default: 1,
      min: 1,
      max: levelConfig.maxLevel,
    },
    exp: {
      type: Number,
      default: 0,
      min: 0,
    },
    coins: {
      type: Number,
      default: 0,
      min: 0,
    },
    income: {
      type: Number,
      default: 0,
      min: 0,
    },
    badges: [
      {
        name: String,
        icon: String,
        obtainTime: Date,
      },
    ],
    titles: [
      {
        name: String,
        icon: String,
        obtainTime: Date,
      },
    ],
    privileges: [String],
    vipLevel: {
      type: Number,
      default: 0,
      min: 0,
      max: 4,
    },
    vipExpireTime: Date,
    roomId: {
      type: String,
      unique: true,
      sparse: true,
    },
    followers: {
      type: Number,
      default: 0,
      min: 0,
    },
    following: {
      type: Number,
      default: 0,
      min: 0,
    },
    blockedUsers: [String],
    lastLoginTime: Date,
    lastLoginIp: String,
    status: {
      type: String,
      enum: ['active', 'banned', 'deleted'],
      default: 'active',
    },
    isAnchor: {
      type: Boolean,
      default: false,
    },
    anchorInfo: {
      category: String,
      tags: [String],
      description: String,
      notice: String,
      totalLiveTime: {
        type: Number,
        default: 0,
        min: 0,
      },
      totalIncome: {
        type: Number,
        default: 0,
        min: 0,
      },
      fansCount: {
        type: Number,
        default: 0,
        min: 0,
      },
      guardCount: {
        type: Number,
        default: 0,
        min: 0,
      },
    },
    bankInfo: {
      realName: String,
      idCard: String,
      bankName: String,
      bankAccount: String,
      bankBranch: String,
    },
    settings: {
      notification: {
        follow: { type: Boolean, default: true },
        gift: { type: Boolean, default: true },
        message: { type: Boolean, default: true },
        roomStart: { type: Boolean, default: true },
      },
      privacy: {
        showLastSeen: { type: Boolean, default: true },
        showPhone: { type: Boolean, default: false },
        allowPrivateMessage: { type: Boolean, default: true },
      },
      display: {
        theme: {
          type: String,
          enum: ['light', 'dark'],
          default: 'light',
        },
        fontSize: {
          type: Number,
          default: 14,
          min: 12,
          max: 20,
        },
        language: {
          type: String,
          default: 'zh-CN',
        },
      },
    },
  },
  {
    timestamps: true,
  }
)

// 密码加密
UserSchema.pre('save', async function (next) {
  if (!this.isModified('password')) return next()

  try {
    const salt = await bcrypt.genSalt(10)
    this.password = await bcrypt.hash(this.password, salt)
    next()
  } catch (err) {
    if (err instanceof Error) {
      next(err)
    } else {
      next(new Error('Unknown error occurred while hashing password'))
    }
  }
})

// 密码验证
UserSchema.methods.comparePassword = async function (candidatePassword: string) {
  return bcrypt.compare(candidatePassword, this.password)
}

export const User = mongoose.model<IUser>('User', UserSchema)
